package com.plian.system.service.wf;

import com.plian.Tools.Tools;
import com.plian.Tools.pagedata.PageData;
import com.plian.system.bean.wf.TaskWithForm;
import com.plian.system.config.exception.MyRuntimeException;
import com.plian.system.model.ObjResult;
import com.plian.system.mybatis.base.BaseFlowService;
import com.plian.system.mybatis.base.FlowServiceFactory;
import com.plian.system.service.sys.excel.AutoExcelService;
import com.plian.system.service.sys.user.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

import static com.plian.system.constant.sys.FormTypeConstant.SYS_AUTO_EXCEL;

/**
 * 工作流中对单据操作的服务类
 */
@Service
public class WorkFlowFormService {

    @Autowired
    private FlowServiceFactory flowServiceFactory;

    @Autowired
    private UserService userService;

    @Autowired
    private AutoExcelService autoExcelService;

    @Transactional
    public HashMap<String, Object> submit(int formType, String formId, String code) throws Exception {
        switch (formType) {
            case SYS_AUTO_EXCEL:
                return autoExcelService.submit(formId, code);
            default:
                throw new MyRuntimeException(new ObjResult("未知的单据类型！"));
        }
    }

    @Transactional
    public HashMap<String, Object> submit(int formType, String formId) throws Exception {
        BaseFlowService baseFlowService = flowServiceFactory.getFlowService(formType);
        if (baseFlowService == null){
            throw new MyRuntimeException("未知的单据类型！");
        }
        return baseFlowService.commit(formId);
    }

    @Transactional
    public void reject(int formType, String formId, int formState, String comment) throws Exception {
        BaseFlowService baseFlowService = flowServiceFactory.getFlowService(formType);
        if (baseFlowService == null){
            throw new MyRuntimeException("未知的单据类型！");
        }
        baseFlowService.reject(formId, formState, comment);
    }

    @Transactional
    public void finish(int formType, String formId) {
        BaseFlowService baseFlowService = flowServiceFactory.getFlowService(formType);
        if (baseFlowService == null){
            throw new MyRuntimeException("未知的单据类型！");
        }
        baseFlowService.finish(formId);
    }

    public void fillFormData(List<? extends TaskWithForm> taskList) {
        Map<Integer, List<String>> grouped = taskList.stream().collect(Collectors.groupingBy(TaskWithForm::getFormType, Collectors.mapping(TaskWithForm::getFormId, Collectors.toList())));
        for (Map.Entry<Integer, List<String>> entry : grouped.entrySet()) {
            entry.setValue(entry.getValue().stream().distinct().collect(Collectors.toList()));
        }
        Map<String, List<TaskWithForm>> taskFormMap = taskList.stream().collect(Collectors.groupingBy(TaskWithForm::getFormId, Collectors.toList()));
        for (Map.Entry<Integer, List<String>> formType : grouped.entrySet()) {
            BaseFlowService baseFlowService = flowServiceFactory.getFlowService(formType.getKey());
            if (baseFlowService == null){
                throw new MyRuntimeException("未知的单据类型！");
            }
            fillFormData(taskFormMap, baseFlowService.findByIds(formType.getValue()));
        }
    }


    private void fillFormData(Map<String, List<TaskWithForm>> taskFormMap, List<PageData> pdList) {
        for (PageData pd : pdList) {
            if (Tools.notEmpty(pd.getString("id"))) {
                for (TaskWithForm taskWithForm : taskFormMap.get(pd.getString("id"))) {
                    String applicant_name = userService.findIdForName(taskWithForm.getStarterId());
                    pd.put("applicant_name", applicant_name);
                    taskWithForm.setFormInfoIntoTask(pd);
                }
            }
        }
    }

    public List<PageData> get(int formType, String formId, String code) {
        if (formType == SYS_AUTO_EXCEL){
            return autoExcelService.findHistoryByIds(Arrays.asList(formId), code);
        }
        BaseFlowService baseFlowService = flowServiceFactory.getFlowService(formType);
        if (baseFlowService == null){
            throw new MyRuntimeException("未知的单据类型！");
        }
        List<String> ids = Collections.singletonList(formId);
        return baseFlowService.findByIds(ids);
    }

    public void goBackToStash(int formType, String formId) {
        BaseFlowService baseFlowService = flowServiceFactory.getFlowService(formType);
        if (baseFlowService == null){
            throw new MyRuntimeException("未知的单据类型！");
        }
        baseFlowService.goBackToStash(formId);
    }
}
